ST_NIPC		stCabecera;  //Donde voy guardando la info que recibo del RECV
int newSock;
int cantThread;
char bufferleidos[500];
pthread_t threadPPD;
//Variables de Select
fd_set readfds;										/* CREO BOLSA DE LECTURA TEMP PARA SELECT */
fd_set master;										/* CREO BOLSA MAESTRA DE LECTURA */
int fdmax,i;										/* NUMERO MAXIMO DE FD. */
struct timeval TimeoutSelect; 		/* ULTIMO PARAMETRO DEL SELECT*/
int enSincro = 0;
int sincroError = 0; //Para controlar la caida de algun disco en SINCROfuera del HILO
sem_t sem_pedidos;
int recibirSincro();
/*============================================================================
SeparaCadena()
============================================================================*/
void SeparaCadena(char *sParametro,char *sValor,char *cadena) {

   int		iConta1=0,iConta2=0;

   strcpy(sParametro,cadena);

   while(sParametro[iConta1]!='='){
         iConta1++;
	}

	sParametro[iConta1]='\0';
    iConta1++;
    while(cadena[iConta1]!='\n') {
        sValor[iConta2]=cadena[iConta1];
	    iConta1++;iConta2++;
	 }

    sValor[iConta2]='\0';
}

/*============================================================================
cargarConfiguracion()
Lee el archivo de configuracion y carga los datos a la estructura del PRAID
============================================================================*/

int cargarConfiguracion() {

	FILE		*pArch;
	char		sParam[60],sValor[60],Aux[60];

	memset(Aux,'\0',60);

	if ((pArch = fopen("PRAIDconfig.txt", "r"))==NULL) {

		return 0;
	 }

	while (!feof(pArch)) {
		fgets(Aux,60,pArch);
		SeparaCadena(sParam,sValor,Aux);
		
		if(strcmp(sParam,"IP")==0)
			strcpy(stPRAID.szIp, sValor);
		if(strcmp(sParam,"PUERTO")==0)
			stPRAID.iPuerto = atoi(sValor);
		if(strcmp(sParam,"FLAGCONSOLA")==0)
			stPRAID.iFlag = atoi(sValor);
		if(strcmp(sParam,"SINCRO")==0)
			stPRAID.iSinc = atoi(sValor);
	}

	fclose(pArch);
	return 1;
}

/*============================================================================
iniciarLog()
Abre el archivo log y escribe el encabezado. Recibe como parametros:
- *nombreLog: nombre del archivo log a crearse.
============================================================================*/
void iniciarLog( const char *nombreLog )
{
	FILE		*pArchLog;
	time_t		tiempo;
	struct tm	*ptm;

	time(&tiempo);
	ptm = localtime(&tiempo );

	pArchLog = fopen(nombreLog,"a");

	fprintf(pArchLog, "Fecha\t  NombreProceso\t[PIDproceso]  [ThreadID]:TipoLog Dato\n");
	fprintf(pArchLog, "************************************************************\n");

	fclose(pArchLog);
}

/*============================================================================
log()
Abre el archivo log y escribe al final. Recibe como parametros:
- *nombreLog: nombre del archivo log.
- *name: puntero al nombre del proceso.
- *type: tipo de mensaje (ERROR, INFO, etc).
- *log: puntero a la cadena, que contiene el mensaje a escribir en el archivo.
============================================================================*/
void log( char nombreLog[], char name[], char type[], char log[])
{
	FILE		*pArchLog;
	time_t		tiempo;
	struct tm	*ptm;

	time(&tiempo);
	ptm = gmtime(&tiempo );

	pArchLog = fopen(nombreLog,"a");

	fprintf(pArchLog, "[%2d:%02d:%02d]  [%s]\t[%d]\t\t[%d]\t[%s]\t[%s]\n",ptm->tm_hour, ptm->tm_min, ptm->tm_sec, name, getpid(), pthread_self(), type, log);
/*%2d:%02d:%04d - ptm->tm_mday, ptm->tm_mon+1, ptm->tm_year+1900, */
	fclose(pArchLog);
}

int existePPD(char p[]){

lPPd *ptrAux;

ptrAux = ptrPPD;

	 while (ptrAux != NULL){
	 
		if(strcmp(ptrAux->ppdid, p) == 0){
		
			return 1;
		}
		ptrAux=ptrAux->next;
	}
	
 return 0;
}

int InsertaListaPPD(int newSock,char szPayload[]){

lPPd *ptr, *ptrAct;
uint16_t cilindro;
uint16_t cabeza;
uint16_t sector;
char IdPPD[5];
char *p;

		
		   p=strtok(szPayload, "|");
		   strcpy(IdPPD, p);
		   printf("El id del PPD es:%s\n", p);
		   p=strtok(NULL, "|");
		   cilindro = atoi(p);
		   p=strtok(NULL, "|");
		   cabeza = atoi(p);
		   p=strtok(NULL, "|");
		   sector = atoi(p);
		   
		if(existePPD(IdPPD) == 0){
		
		   ptr = (lPPd *)malloc(sizeof(lPPd));
		   
		   if ( ptr != NULL){
		   
				   strcpy(ptr->ppdid, IdPPD);
				   ptr->cantSectores = cilindro * sector;
				   ptr->carga = 0;
				   ptr->socket = newSock;
				   ptr->next = NULL;
				   ptrAct = ptrPPD;
				  
								if (ptrAct != NULL){
								
									while (ptrAct->next != NULL){
										ptrAct = ptrAct->next;
									}
									
									ptrAct->next = ptr; //lo inserto un la ultima posicion
									//CONSOLA
									if (stPRAID.iFlag == 1)
									{
										printf("=====================================================================\n");
										printf("\t\t===NUEVO DISCO CONECTADO CON ID %s ===\n",ptr->ppdid);
										printf("=====================================================================\n");
										log("praidLog.txt","PRAID","INFO","===NUEVO DISCO CONECTADO===\n");
									}
								}
								else{
									ptr->sincronized = 1;
									ptrPPD = ptr;   //es el primero
									printf("Proceso PRAID en ejecucion\n");
									if (stPRAID.iFlag == 1)
									{
										printf("=====================================================================\n");
										printf("\t\t===PRIMER DISCO CONECTADO CON ID %s ===\n",ptr->ppdid);
										printf("=====================================================================\n");
										log("praidLog.txt","PRAID","INFO","===PRIMER DISCO CONECTADO===\n");
									}
								}
			}
			else{
				printf("Error no se pudo alocar memoria para el Nodo del disco\n");
				return -1;
			
			}
		}
		else{
			printf("El PPD ya existe\n");
			close(newSock);
			FD_CLR(newSock,&master);
			return 1;
		}

return 0;				
}

int cantNodoListaPPD(){

lPPd *ptrAux;
int contador=0;

ptrAux = ptrPPD;

	 while (ptrAux != NULL){
		contador++;
		ptrAux=ptrAux->next;
	}
 return contador;
 }
 
int cantNodoListaPFS(){

	lPFS *ptrAux;
	int contador=0;

	ptrAux = ptrPFS;

	while (ptrAux != NULL){
		contador++;
		ptrAux=ptrAux->next;
	}
	return contador;
}

int eliminarPPD(int sock )
{
	lPPd  *p, *q;
	int encontro=0;
	p = ptrPPD;
	q = NULL;
	//sectoresPedidos();
	//printf("voy a eliminar el sector: %i!\n",info.sector);
	while ((p!=NULL) && (encontro==0))
	{
		if ((p->socket==sock))
		{
			encontro =1;
			if ( q == NULL)
			{
				if( p->next == NULL)
				{
					ptrPPD = NULL;
					free(p);
					return 0;
				}else
				{
					ptrPPD = p->next;
					free(p);
					return 0;
				}
			}else
			{
				q->next = p->next;
				p->next = NULL;
				free(p);
				return 0;
			}

		}else
		{
			q=p;
			p=p->next;
		}
	}
	return 0;
}

 int actualizaSincronizedPPD(int s){

 lPPd *ptrAux;
 ptrAux = ptrPPD;

 	//busco el nodo de menor carga
 	while(ptrAux != NULL){

 		if(ptrAux->socket == s){
 			ptrAux->sincronized = 1;
			return 0;

 		}
 		ptrAux = ptrAux->next;
 	}
 return 0;
 }
//Funcion del ThreadPPD
//void sincronizarPPD(void * parametros){
 int recibirSincro()
 {
	 lPPd *ptrPPDMaster;
	 ptrPPDMaster = ptrPPD;
	 for(i=0; i < ptrPPDMaster->cantSectores; i++)
	 		{
	 			if(recv(ptrPPDMaster->socket,(void*)&stCabecera, sizeof(ST_NIPC),MSG_WAITALL)	< 0)
	 			{
	 				close (ptrPPDMaster->socket);
	 				FD_CLR(ptrPPDMaster->socket ,&master);
	 				log("praidLog.txt","PRAID","ERROR","Error al recibir Sector del Disco Maestro");
	 				perror("Error al recibir Sector del Disco Maestro");
	 				printf("Error del socket:%d", ptrPPDMaster->socket);
	 				eliminarPPD(ptrPPDMaster->socket);
	 				return -1;
	 			}

	 			if (stPRAID.iFlag == 1)
	 			{
	 				printf("Recibi correctamente la rta del sector %d\n", stCabecera.sector);	// ahora el sector que recibo puede no ser "i"
	 				log("praidLog.txt","PRAID","INFO","Recibi correctamente la rta del sector");
	 			}

	 			// Una vez que recibi ME escribo, siendo yo el disco Nuevo

	 			stCabecera.ucType = WRITESINCRO;
	 			stCabecera.lPayload = sizeof(stCabecera.buffer);	// WRITESECTOR manda contenido en el buffer (lPayload != 0)

	 			if( send( newSock, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
	 			{
	 				close( newSock );
	 				FD_CLR(newSock ,&master);
	 				log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND del WRITESECTOR Sincronizacion");
	 				perror("Error en el send WRITESINCRO Sincronizacion");
	 				eliminarPPD(newSock);
	 				return -1;
	 			}
	 			else
	 			{
	 				if (stPRAID.iFlag == 1)
	 				{
	 					printf("Writeok: %u, Sector %d\n", stCabecera.ucType, stCabecera.sector);	// ahora el sector que recibo puede no ser "i"
	 					log( "praidLog.txt", "PRAID", "INFO", "Se envio WRITESECTOR al PPD para Sincro");
	 				}
	 			}
	 			//sem_post(&sem_pedidos);
	 		}
 }

int sincronizarPPD(){
	lPPd *ptrPPDMaster;
	int i;
	time_t  iniSincro, finSincro;
	pthread_attr_t attr;
	/*Controlar si la ListaPPD es >= 2 para realizar una sincronizacion,
	significa que hay varios discos conectados, sino no sicroniza porque es el primero
	*/
	//sem_init(&sem_pedidos, 0, 5000);

	if(cantNodoListaPPD()>1)
	{
		pthread_attr_init(&attr);
		pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
		pthread_create(&threadPPD, &attr, (void*)&recibirSincro, NULL);

		ptrPPDMaster = ptrPPD;
		
		(void) time(&iniSincro);//Comienzo de la sincronizacion
		printf("Empezo la medicion del tiempo\n");

		for(i=0; i < ptrPPDMaster->cantSectores; i++)
		{
			if((i%500==0) || (i==ptrPPDMaster->cantSectores-1)){
				printf("Sectores %d\n",i);
			}

			stCabecera.ucType = GETSECTOR;
			stCabecera.sector = i;
			stCabecera.lPayload = 0;	// GETSECTOR no manda nada en el buffer (lPayload = 0)

			if( send( ptrPPDMaster->socket, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
			{
				close( ptrPPDMaster->socket );
				FD_CLR(ptrPPDMaster->socket ,&master);
				log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND del GETSECTOR Sincronizacion");
				perror("Error en el send GETSECTOR Sincronizacion");
				eliminarPPD(ptrPPDMaster->socket);
				return -1;
			}

			if (stPRAID.iFlag == 1)
			{
				printf("Envie correctamente el pedido de sector %d\n", i);
				log( "praidLog.txt", "PRAID", "INFO", "Se envio GETSECTOR al PPD para Sincro");
			}
			//sem_wait(&sem_pedidos);
		}

//		for(i=0; i < ptrPPDMaster->cantSectores; i++)
//		{
//			if(recv(ptrPPDMaster->socket,(void*)&stCabecera, sizeof(ST_NIPC),MSG_WAITALL)	< 0)
//			{
//				close (ptrPPDMaster->socket);
//				FD_CLR(ptrPPDMaster->socket ,&master);
//				log("praidLog.txt","PRAID","ERROR","Error al recibir Sector del Disco Maestro");
//				perror("Error al recibir Sector del Disco Maestro");
//				printf("Error del socket:%d", ptrPPDMaster->socket);
//				eliminarPPD(ptrPPDMaster->socket);
//				return -1;
//				//pthread_exit(NULL);
//			}
//
//			if (stPRAID.iFlag == 1)
//			{
//				printf("Recibi correctamente la rta del sector %d\n", stCabecera.sector);	// ahora el sector que recibo puede no ser "i"
//				log("praidLog.txt","PRAID","INFO","Recibi correctamente la rta del sector");
//			}
//
//			// Una vez que recibi ME escribo, siendo yo el disco Nuevo
//
//			stCabecera.ucType = WRITESINCRO;
//			stCabecera.lPayload = sizeof(stCabecera.buffer);	// WRITESECTOR manda contenido en el buffer (lPayload != 0)
//
//			if( send( newSock, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
//			{
//				close( newSock );
//				FD_CLR(newSock ,&master);
//				log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND del WRITESECTOR Sincronizacion");
//				perror("Error en el send WRITESINCRO Sincronizacion");
//				eliminarPPD(newSock);
//				return -1;
//				//thread_exit(NULL);
//			}
//			else
//			{
//				if (stPRAID.iFlag == 1)
//				{
//					printf("Writeok: %u, Sector %d\n", stCabecera.ucType, stCabecera.sector);	// ahora el sector que recibo puede no ser "i"
//					log( "praidLog.txt", "PRAID", "INFO", "Se envio WRITESECTOR al PPD para Sincro");
//				}
//			}
//		}

		/*---------------------- CAMBIO DE LOS SEND TODOS JUNTOS (fin) ----------------------------------------------------------*/

//		for(i=0; i < ptrPPDMaster->cantSectores; i++)
//		//for(i=0; i < 5; i++)
//		{
//			if((i%100==0) || (i==ptrPPDMaster->cantSectores-1)){
//				printf("Sectores %d\n",i);
//			}
//			stCabecera.ucType = GETSECTOR;
//			stCabecera.sector = i;
//			stCabecera.lPayload = sizeof(stCabecera.buffer);
//
//			if( send( ptrPPDMaster->socket, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
//			{
//				close( ptrPPDMaster->socket );
//				FD_CLR(ptrPPDMaster->socket ,&master);
//				log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND del GETSECTOR Sincronizacion");
//				perror("Error en el send GETSECTOR Sincronizacion");
//				eliminarPPD(ptrPPDMaster->socket);
//				return -1;
//				//pthread_exit(NULL);
//			}
//
//			if (stPRAID.iFlag == 1)
//			{
//				printf("Envie correctamente el pedido de sector %d\n", i);
//				log( "praidLog.txt", "PRAID", "INFO", "Se envio GETSECTOR al PPD para Sincro");
//			}
//
//			if(recv(ptrPPDMaster->socket,(void*)&stCabecera, sizeof(ST_NIPC),MSG_WAITALL)	< 0)
//			{
//				close (ptrPPDMaster->socket);
//				FD_CLR(ptrPPDMaster->socket ,&master);
//				log("praidLog.txt","PRAID","ERROR","Error al recibir Sector del Disco Maestro");
//				perror("Error al recibir Sector del Disco Maestro");
//				printf("Error del socket:%d", ptrPPDMaster->socket);
//				eliminarPPD(ptrPPDMaster->socket);
//				return -1;
//				//pthread_exit(NULL);
//			}
//
//			if (stPRAID.iFlag == 1)
//			{
//				printf("Recibi correctamente la rta del sector %d\n", i);
//				log("praidLog.txt","PRAID","INFO","Recibi correctamente la rta del sector");
//			}
//			/*
//			 * Una vez que recibi ME escribo, siendo yo el disco Nuevo
//			 */
//
//			stCabecera.ucType = WRITESINCRO;
//
//			if( send( newSock, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
//			{
//				close( newSock );
//				FD_CLR(newSock ,&master);
//				log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND del WRITESECTOR Sincronizacion");
//				perror("Error en el send WRITESINCRO Sincronizacion");
//				eliminarPPD(newSock);
//				return -1;
//				//thread_exit(NULL);
//			}
//			else
//			{
//				if (stPRAID.iFlag == 1)
//				{
//				printf("Writeok: %u, Sector %d\n",stCabecera.ucType,i);
//				log( "praidLog.txt", "PRAID", "INFO", "Se envio WRITESECTOR al PPD para Sincro");
//				}
//			}


			//Controlo la llegada WRITESECTOROK de parte del PFS
//			if(recv( newSock,(void*) &stCabecera, sizeof(ST_NIPC),MSG_WAITALL)	< 0)
//			{
//				close ( newSock );
//				FD_CLR(newSock ,&master);
//				log("praidLog.txt","PRAID","ERROR","Error al recibir el WRITEOK de mi DISCO");
//				perror("Error al recibir la confirmacion de escritura");
//				printf("\nError del socket:%d", newSock);
//				eliminarPPD(newSock);
//				return -1;
//				//pthread_exit(NULL);
//			}

			//Verifico que haya llegado la confirmacion de escritura
//			if(stCabecera.ucType == WRITESECTOROK){
//				if (stPRAID.iFlag == 1)
//				{
//					printf("CONSOLA - Se escribio el sector en DISCO\n");
//					log("praidLog.txt","PRAID","INFO","CONSOLA - Se escribio el sector DISCO");
//				}
//			}
//			else
//				log("praidLog.txt","PRAID","ERROR","No se recibio la confirmacion de WRITESECTOROK");

			//lPayload
//		}//Cierro el For
		int* retorno=malloc(sizeof(int));
		pthread_join(threadPPD,&retorno);
		(void) time(&finSincro);
		log("praidLog.txt","PRAID","INFO","Se finalizo la sincronizacion");
		printf("\n Tiempo transcurrido durante la Sincronizacion = %d segundos\n", (int) finSincro-iniSincro);


		stCabecera.ucType = SINCROFINISHED;

		if( send( newSock, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) < 0 )
		{
			close( newSock );
			FD_CLR(newSock ,&master);
			log( "praidLog.txt", "PRAID", "ERROR","Error en el SEND de SINCROFINISHED");
			perror("Error en el send SINCROFINISHED");
			eliminarPPD(newSock);
			return -1;
		}

		if (stPRAID.iFlag == 1)
		{
			printf("===========CONSOLA===========\n");
			printf("Se finalizo la sincronizacion\n");
			printf("\n Tiempo transcurrido durante la Sincronizacion = %d segundos\n", (int) finSincro-iniSincro);
		}

	}//Cierro el Else
	enSincro = 0;
	
	return 0;
}//Cierro el If

int insertarPedidosPFS(char p[5], ST_NIPC st,int s, int est, int spfs){

lPFS *ptr, *ptrAct;
ptr = (lPFS *)malloc(sizeof(lPFS));

 if ( ptr != NULL){
		
			memcpy((void *)&(ptr->stCab), &st, sizeof(ST_NIPC));
			strcpy(ptr->ppdid, p);
			ptr->sockPPD = s;
			ptr->sockPFS = spfs;
			ptr->estado = est;
			ptr->next = NULL;
			ptrAct = ptrPFS;

						if (ptrAct != NULL){

							while (ptrAct->next != NULL){
								ptrAct = ptrAct->next;
							}

							ptrAct->next = ptr; //lo inserto un la ultima posicion
						}
						else{
							ptrPFS = ptr;   //es el primero
						}
	}
	else{
		printf("Error no se pudo alocar memoria para el Nodo del pedido GET de PFS");
		return -1;

	}

return 0;
}

lPPd *selectDiscRead(){

lPPd *ptrAux, *selec;
unsigned long carga; //Esto llega hasta 65.500
ptrAux = ptrPPD;

	carga = 600000;
	//selec=(lPPd *)malloc(sizeof(lPPd));
	
	//busco el nodo de menor carga
	while(ptrAux != NULL){
		//printf("paso al sig %u \n", ptrAux->carga);
		if(ptrAux->carga < carga){
				carga = ptrAux->carga;
				selec = ptrAux;
		}
		ptrAux = ptrAux->next;
	}
	printf("PPD:%s  Carga: %u \n",selec->ppdid, selec->carga);
return selec;

}

int replanificarPedidos(int s){

lPFS *ptrAux;


ptrAux = ptrPFS;

	 while (ptrAux != NULL){
	 
		if(ptrAux->sockPPD == s){
			ptrAux->estado = -1;
		}
		
		ptrAux=ptrAux->next;
	}
 return 0;

}

void atenderPedPfs(){

lPPd *ListaPFSAux;
lPFS *ptrAux, *ptrAnt, *ptrAct;
ptrAnt = NULL;
ptrAux = ptrPFS;
ptrAct = ptrPFS;

		while (ptrAux != NULL){
		
			if ( ptrAux->estado == -1){

				switch(ptrAux->stCab.ucType)
				{
					case WRITESECTOR:  //Me solicitan Escritura
					ListaPFSAux = ptrPPD;
					while (ListaPFSAux != NULL) {
					
						if( send( ListaPFSAux->socket, &ptrAux->stCab, sizeof(ST_NIPC), 0 ) < 0 )
						{
							close( ListaPFSAux->socket );
							log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del WRITESECTOR pedido por PFS");
							perror("Error en el send WRITESECTOR pedido por PFS");
						}
					}
					if(ptrAux == ptrPFS){
						ptrPFS = NULL;
						ptrAct = NULL;
						ptrAux = NULL;
					} 
					else{
						ptrAnt->next = ptrAct->next;
						ptrAct->next = NULL;
						ptrAct = ptrAnt->next;
						ptrAux = ptrAnt;	
					}

					break;

					case GETSECTOR://Preguntar por Read(GET) (PFS)
			
							ListaPFSAux = selectDiscRead();
							ListaPFSAux->carga = ListaPFSAux->carga + 1; 
							strcpy(ptrAux->ppdid , ListaPFSAux->ppdid);
							ptrAux->sockPPD = ListaPFSAux -> socket;
							ptrAux->estado = 1;
							if( send( ListaPFSAux->socket, &ptrAux->stCab, sizeof(ST_NIPC), 0 ) < 0 )
							{
								close( ListaPFSAux->socket );
								log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del GETSECTOR pedido por PFS");
								perror("Error en el send GETSECTOR pedido por PFS");
								ptrAux->estado = -1;
							}
							else
								log( "praidLog.txt", "PRAID", "INFO", "Se envio GETSECTOR al PPD por pedido PFS");
						
						break;

				}//fin del switch
				
			}
				
				if(ptrAux != NULL){
				ptrAux = ptrAux->next;
				}
		}


}

int eliminarPedido(int s, int spfs, ST_NIPC rp, unsigned char type){

lPFS *ptrAux, *ptrAnt;
ptrAnt = NULL;
ptrAux = ptrPFS;
char *p;
	//busco el nodo de menor carga
	while(ptrAux != NULL){

		if(ptrAux->sockPPD == s && ptrAux->sockPFS == spfs){

			if (ptrAux->stCab.sector == rp.sector && ptrAux->stCab.ucType == type && ptrAux->estado != -1 ){
			
				if(ptrAnt == NULL){
				
					if(ptrAux->next != NULL){
						
						ptrPFS = ptrAux->next;
						ptrAux->next = NULL;
						free(ptrAux);
						return 0;
					}
					else{
						ptrPFS = NULL;
						free(ptrAux);
						return 0;
					}
					
				}
				else{
				ptrAnt->next = ptrAux->next;
				ptrAux->next = NULL;
				free(ptrAux);
				return 0;
				//free(ptrAux);
				}
			}
		}
		ptrAnt = ptrAux;
		ptrAux = ptrAux->next;
	}
return 0;	
}

void atenderMensajePFS(int sockPFS, ST_NIPC stCabecera){

char ppdID[5];
int sock;
lPPd *ListaPFSAux;
ListaPFSAux = ptrPPD;

    // gestionar datos de un cliente
		switch(stCabecera.ucType)
		{
			case WRITESECTOR:  //Me solicitan Escritura
			/*Escribir en toda la lista de Discos lo solicitado por PFS*/
				strcpy(ppdID,"PPPP");

				insertarPedidosPFS(ppdID,stCabecera,0,1,sockPFS);

				ListaPFSAux = ptrPPD;

				while(ListaPFSAux != NULL)
				{
					//Lo que recibo es igual a lo que quiero escribir en PPD
					if( send( ListaPFSAux->socket, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) <= 0 )
					{
						close( ListaPFSAux->socket );
						FD_CLR(ListaPFSAux->socket ,&master);
						log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del WRITESECTOR pedido por PFS");
						perror("Error en el send WRITESECTOR pedido por PFS");
					}
					else{
						log( "praidLog.txt", "PRAID", "INFO", "Se envio WRITESECTOR al PPD por pedido");
						if (stPRAID.iFlag == 1)
						{
							printf("===========CONSOLA===========\n");
							printf("Se envio Writesector a todos los discos\n");
						}

					}

					ListaPFSAux = ListaPFSAux->next;
				}//Fin del While que recorre la lista PPD para escribirla

			break;

			case GETSECTOR://Preguntar por Read(GET) (PFS)
			
			//ALGORITMO de seleccion para escoger disco
			ListaPFSAux = selectDiscRead();
			ListaPFSAux->carga = ListaPFSAux->carga + 1; 
			sock = ListaPFSAux -> socket;
			strcpy(ppdID,ListaPFSAux->ppdid);
			insertarPedidosPFS(ppdID,stCabecera, sock,1,sockPFS);
			//Lo que recibo es igual que lo que mando. Sin cambios en St_NIPC

				if( send( sock, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) <= 0 )
				{
					close( sock );
					FD_CLR(sock ,&master);
					log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del GETSECTOR pedido por PFS");
					perror("Error en el send GETSECTOR pedido por PFS");
					eliminarPPD(sock);
					replanificarPedidos(sock);
					if(cantNodoListaPPD(sock) == 0){
						printf("Se cierra todo porque no hay mas sincronizados\n");
						exit(-1);
					}
				}
				else{
					log( "praidLog.txt", "PRAID", "INFO", "Se envio GETSECTOR al PPD por pedido PFS");
					if (stPRAID.iFlag == 1)
					{
						printf("===========CONSOLA===========\n");
						printf("Se envio Lectura al PPD: %s\n", ppdID);
					}
					
				}
	
			break;
			
		}
}

int obtenerSocketPFS(int s, ST_NIPC rp, unsigned char type){

lPFS *ptrAux;
ptrAux = ptrPFS;

	while(ptrAux != NULL){

		if(ptrAux->sockPPD == s){
	
			if (ptrAux->stCab.sector == rp.sector && ptrAux->stCab.ucType == type){
			return ptrAux->sockPFS;
			
			}
		}
		ptrAux = ptrAux->next;
	}
return 0;
	
}

int restarCarga(int socketDisco){

	lPPd *ptrAux;
	ptrAux = ptrPPD;

	while(ptrAux != NULL)
	{
		if(ptrAux->socket == socketDisco)
		{
			ptrAux->carga = ptrAux->carga-1;

			printf("Carga: %u\n",ptrAux->carga );

			log( "praidLog.txt", "PRAID", "INFO","Se resto la carga");
			return 1;
		}
		ptrAux = ptrAux->next;
	}
	return 0;
}

int atenderMensajePPD(int sockDisco,ST_NIPC stCabecera){
int sockPFS;
	switch(stCabecera.ucType)
	{

		case RTASECTOR: //Recibo Respuesta OK del PPD de Lectura

				printf("respuesta getsector: %u\n", stCabecera.ucType );
				
				sockPFS = obtenerSocketPFS(sockDisco, stCabecera, 0x10);
				printf("SocketPFS: %u\n",sockPFS);
				
				if( send( sockPFS, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) <= 0 )
				{
					close(sockPFS);
					FD_CLR(sockPFS,&master);
					log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del RTASECTOR al PFS");
					perror("Error en el send RTASECTOR enviando al PFS");
				}
				else
					{
						log( "praidLog.txt", "PRAID", "INFO", "Se envio RTASECTOR al PFS");
						eliminarPedido(sockDisco, sockPFS, stCabecera, 0x10);
					}

			break;

		case WRITESECTOROK:
				sockPFS = obtenerSocketPFS(sockDisco, stCabecera, 0x12);
				 if( send( sockPFS, &stCabecera, sizeof(ST_NIPC), MSG_NOSIGNAL ) <=0 )
				 {
					 close( sockPFS );
					 FD_CLR(sockPFS,&master);
					 log( "praidLog.txt", "PPD", "ERROR","Error en el SEND del RTASECTOR al PFS");
					 perror("Error en el send RTASECTOR enviando al PFS");
					
				 }
				else{
					log( "praidLog.txt", "PRAID", "INFO", "Se envio WRITESECTOROK al PFS");
					eliminarPedido(sockDisco, sockPFS, stCabecera, 0x12);
				}

			/*Recibir respuesta del PPD que se escribio en los discos*/
			break;
		default:
			printf("El contenido de ucType no es uno esperado \n");
			break;

		}//fin del switch

return 0;
}

int buscarConexPPD(int s){

lPPd *ptrAux;
ptrAux = ptrPPD;

	//busco el nodo de menor carga
	while(ptrAux != NULL){

		if(ptrAux->socket == s){
		return s;

		}
		ptrAux = ptrAux->next;
	}
return -1;
}
